#ifndef __DATA_UTIL_FLAGS__
#define __DATA_UTIL_FLAGS__

namespace woe
{
	template<int length>
	class Flags
	{
		static const short	len_int = (length>>5)+1;
		static const short	len_cha = (length>>3)+1;

		public:
		Flags(const char& val = 0)
		{
			memset((void*)&_data, val, sizeof(_data));
		}

		Flags(const Flags& flg)
		{
			memcpy((void*)&_data, (void*)&flg._data, sizeof(_data));
		}

		Flags& operator = (const Flags& flg)
		{
			memcpy((void*)&_data, (void*)&flg._data, sizeof(_data));
			return *this;
		}

		bool set(const int * val)
		{
			memcpy((void*)&_data, (void*)val, sizeof(_data));
			return true;
		}

		bool set(const char * val)
		{
			memcpy((void*)&_data, (void*)val, sizeof(_data));
			return true;
		}

		bool set(const short& idx, const int& val)
		{
			if (idx<len_int)
			{
				_data._i[idx] = val;
				return true;
			}
			else
			{
				return false;
			}
		}

		bool set(const short& idx, const char& val)
		{
			if (idx<len_cha)
			{
				_data._c[idx] = val;
				return true;
			}
			else
			{
				return false;
			}
		}

		bool get(const short& idx, int& val)const
		{
			if (idx<len_int)
			{
				val = _data._i[idx];
				return true;
			}
			else
			{
				return false;
			}
		}

		bool get(const short& idx, char& val)const
		{
			if (idx<len_cha)
			{
				val = _data._c[idx];
				return true;
			}
			else
			{
				return false;
			}
		}

		void setFlg(const short& idx)
		{
			short idx_b = idx>>3;
			short flg = 1<< (idx&7);

			if (idx_b<len_cha)
			{
				_data._c[idx_b] |= flg; 
			}
		}

		void clrFlg(const short& idx)
		{
			short idx_b = idx>>3;
			short flg = ~( 1<< (idx&7) );

			if (idx_b<len_cha)
			{
				_data._c[idx_b] &= flg; 
			}
		}
		bool hasFlg(const short& idx) const
		{
			short idx_b = idx>>3;
			short flg = 1<< (idx&7);

			if (idx_b<len_cha)
			{
				return (_data._c[idx_b] & flg)!=0; 
			}
			else
			{
				return false;
			}
		}

		protected:
		union Data
		{
			int		_i[len_int];
			char	_c[len_cha];
		};

		Data	_data;
	};

}

#endif


